<!DOCTYPE html><html lang="zh-Hans"><head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"><meta name="description" content="iOS开发者指南：从objectivec到Swift的学习"><meta name="keywords" content="Swift"><meta name="author" content="kyren"><meta name="copyright" content="kyren"><title>iOS开发者指南：从objectivec到Swift的学习 | Kyren's Blog</title><link rel="shortcut icon" href="/melody-favicon.ico"><link rel="stylesheet" href="/css/index.css?version=1.9.0"><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/font-awesome@latest/css/font-awesome.min.css?version=1.9.0"><meta name="format-detection" content="telephone=no"><meta http-equiv="x-dns-prefetch-control" content="on"><link rel="dns-prefetch" href="https://cdn.jsdelivr.net"><link rel="dns-prefetch" href="https://hm.baidu.com"><script>var _hmt = _hmt || [];
(function() {
  var hm = document.createElement("script");
  hm.src = "https://hm.baidu.com/hm.js?cf87fcdbd9ab7cf93d894f7c219ae78f";
  var s = document.getElementsByTagName("script")[0]; 
  s.parentNode.insertBefore(hm, s);
})();</script><meta http-equiv="Cache-Control" content="no-transform"><meta http-equiv="Cache-Control" content="no-siteapp"><script src="https://v1.hitokoto.cn/?encode=js&amp;charset=utf-8&amp;select=.footer_custom_text" defer></script><script>var GLOBAL_CONFIG = { 
  root: '/',
  algolia: undefined,
  localSearch: {"path":"search.xml","languages":{"hits_empty":"找不到您查询的内容:${query}"}},
  copy: {
    success: '复制成功',
    error: '复制错误',
    noSupport: '浏览器不支持'
  },
  hexoVersion: '6.2.0'
} </script><meta name="generator" content="Hexo 6.2.0"></head><body><i class="fa fa-arrow-right" id="toggle-sidebar" aria-hidden="true"></i><div id="sidebar" data-display="true"><div class="toggle-sidebar-info text-center"><span data-toggle="切换文章详情">切换站点概览</span><hr></div><div class="sidebar-toc"><div class="sidebar-toc__title">目录</div><div class="sidebar-toc__progress"><span class="progress-notice">你已经读了</span><span class="progress-num">0</span><span class="progress-percentage">%</span><div class="sidebar-toc__progress-bar"></div></div><div class="sidebar-toc__content"><ol class="toc"><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%B0%9D%E8%AF%95%E4%BD%BF%E7%94%A8Swift-VS-objectivec"><span class="toc-number">1.</span> <span class="toc-text">尝试使用Swift VS objectivec</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%8F%98%E9%87%8F%E5%92%8C%E5%B8%B8%E9%87%8F"><span class="toc-number">2.</span> <span class="toc-text">变量和常量</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%8F%AF%E9%80%89-Optionals-%E7%B1%BB%E5%9E%8B"><span class="toc-number">3.</span> <span class="toc-text">可选(Optionals)类型</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%8F%92%E5%80%BC%EF%BC%88%E6%8B%BC%E6%8E%A5%EF%BC%89"><span class="toc-number">4.</span> <span class="toc-text">字符串插值（拼接）</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%87%BD%E6%95%B0"><span class="toc-number">5.</span> <span class="toc-text">函数</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E6%9E%9A%E4%B8%BE%EF%BC%88Enumerations%EF%BC%89"><span class="toc-number">6.</span> <span class="toc-text">枚举（Enumerations）</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E5%85%83%E7%BB%84%EF%BC%88Tuples%EF%BC%89"><span class="toc-number">7.</span> <span class="toc-text">元组（Tuples）</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#%E7%B1%BB-Classes-%E5%92%8C%E7%BB%93%E6%9E%84-Structures"><span class="toc-number">8.</span> <span class="toc-text">类(Classes)和结构(Structures)</span></a></li></ol></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%AE%9A%E4%B9%89%E7%B1%BB%EF%BC%88Classes%EF%BC%89"><span class="toc-number"></span> <span class="toc-text">定义类（Classes）</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E7%BB%93%E6%9E%84-Structures"><span class="toc-number"></span> <span class="toc-text">结构(Structures)</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E5%B1%9E%E6%80%A7-Properties"><span class="toc-number"></span> <span class="toc-text">属性(Properties)</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#%E8%AE%A1%E7%AE%97%E5%B1%9E%E6%80%A7-Computed-Properties"><span class="toc-number"></span> <span class="toc-text">计算属性(Computed Properties)</span></a></div></div><div class="author-info hide"><div class="author-info__avatar text-center"><img src="https://avatars.githubusercontent.com/u/5827823?v=4"></div><div class="author-info__name text-center">kyren</div><div class="author-info__description text-center">huluo的技术博客</div><div class="follow-button"><a target="_blank" rel="noopener" href="https://github.com/huluo666">Follow Me</a></div><hr><div class="author-info-articles"><a class="author-info-articles__archives article-meta" href="/archives"><span class="pull-left">文章</span><span class="pull-right">239</span></a><a class="author-info-articles__tags article-meta" href="/tags"><span class="pull-left">标签</span><span class="pull-right">41</span></a><a class="author-info-articles__categories article-meta" href="/categories"><span class="pull-left">分类</span><span class="pull-right">29</span></a></div><hr><div class="author-info-links"><div class="author-info-links__title text-center">Links</div><a class="author-info-links__name text-center" target="_blank" rel="noopener" href="http://192.168.2.212:9090/">Jira</a><a class="author-info-links__name text-center" target="_blank" rel="noopener" href="http://192.168.2.212:8090/">Confluence</a><a class="author-info-links__name text-center" target="_blank" rel="noopener" href="http://bloc.leniugame.com/">Leniu</a></div></div></div><div id="content-outer"><div class="no-bg" id="top-container"><div id="page-header"><span class="pull-left"> <a id="site-name" href="/">Kyren's Blog</a></span><i class="fa fa-bars toggle-menu pull-right" aria-hidden="true"></i><span class="pull-right menus">   <a class="site-page" href="/">主页</a><a class="site-page" href="/essay">随笔</a><a class="site-page" href="/archives">归档</a><a class="site-page" href="/tags">标签</a><a class="site-page" href="/categories">分类</a><a class="site-page" href="/about">关于</a></span><span class="pull-right"><a class="site-page social-icon search"><i class="fa fa-search"></i><span> 搜索</span></a></span></div><div id="post-info"><div id="post-title">iOS开发者指南：从objectivec到Swift的学习</div><div id="post-meta"><time class="post-meta__date"><i class="fa fa-calendar" aria-hidden="true"></i> 2017-01-28</time><span class="post-meta__separator">|</span><i class="fa fa-inbox post-meta__icon" aria-hidden="true"></i><a class="post-meta__categories" href="/categories/iOS/">iOS</a></div></div></div><div class="layout" id="content-inner"><article id="post"><div class="article-container" id="post-content"><p>iOS开发者指南：从objectivec到Swift的学习【译】</p>
<p>原文 <a target="_blank" rel="noopener" href="https://www.toptal.com/swift/from-objectivec-to-swift">https://www.toptal.com/swift/from-objectivec-to-swift</a></p>
<p>​     2008年，苹果宣布并发布了iPhone SDK 2.0。这一事件又引发了软件开发的又一次革命，诞生了一批新的开发者。他们现在被认可为iOS开发者。</p>
<p>其中许多开发者以前从未使用过objectivec，这是苹果公司向他们提出的第一个挑战。尽管不熟悉的语法和手动内存管理，但它是非常成功的，帮助成千上万的应用程序上架到App Store。每个版本中，Apple都不断改进objectivec，添加代码块blocks和常量，通过自动引用计数简化内存管理，以及许多指示现代编程语言的其他功能。</p>
<p>​	经过6年对objectivec的改进和工作，苹果决定向开发者提出另一个挑战。 iOS开发者再一次需要学习一门新的编程语言：Swift。 Swift删除了不安全的指针管理，并引入了强大的新功能，同时保持与objectivec和C的交互。</p>
<p>​	Swift 1.0已经是一个稳定而强大的开发平台，在未来几年肯定会以有趣的方式发展。开始探索这个新语言是一个完美的时刻，因为它显然是iOS开发的未来。</p>
<p>本教程的目的是让objectivec开发人员快速了解新的Swift语言特性，帮助您进行下一步，并在日常工作中使用Swift。我不会花太多时间来解释objectivec，我将假定您熟悉iOS开发。</p>
<h4 id="尝试使用Swift-VS-objectivec"><a href="#尝试使用Swift-VS-objectivec" class="headerlink" title="尝试使用Swift VS objectivec"></a>尝试使用Swift VS objectivec</h4><p>为了开始探索Swift，你需要做的就是从App Store下载Xcode，创建一个小程序来实验。本文中提到的所有示例都是这样完成的。</p>
<p>苹果的Swift主页是学习Swift编程的最佳参考。你会发现它是非常宝贵的，直到你完全按照Swift的发展速度，我相信你会经常回到这里。</p>
<h4 id="变量和常量"><a href="#变量和常量" class="headerlink" title="变量和常量"></a>变量和常量</h4><p>在Swift中声明变量是使用var关键字完成的。</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> x <span class="operator">=</span> <span class="number">1</span></span><br><span class="line"><span class="keyword">var</span> s <span class="operator">=</span> <span class="string">&quot;Hello&quot;</span></span><br></pre></td></tr></table></figure>

<p>你会注意到两个变量x和s是不同的类型。 <code>x</code>是一个整数(Integer)，而<code>s</code>是一个字符串(String)。 Swift是一种类型安全的语言，它将从分配的值中推导出变量类型。如果你想让你的代码更具可读性，你可以选择注释变量的类型：</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> y: <span class="type">Int</span></span><br><span class="line">y <span class="operator">=</span> <span class="number">2</span></span><br></pre></td></tr></table></figure>

<p>常量是相似的，但是用<code>let</code>而不是<code>var</code>声明它们。常量的值不需要在编译时知道，但是你必须给它赋值一次。</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> c1 <span class="operator">=</span> <span class="number">1</span>  <span class="comment">//在编译时已知的常量</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> v <span class="operator">=</span> arc4random()</span><br><span class="line"><span class="keyword">let</span> c2 <span class="operator">=</span> v <span class="comment">// 只在运行时才知道的常量(Constant)</span></span><br></pre></td></tr></table></figure>

<p>顾名思义，它们是不可变的，所以下面的代码会导致编译时错误。</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> c <span class="operator">=</span> <span class="number">1</span></span><br><span class="line">c <span class="operator">=</span> <span class="number">3</span>        <span class="comment">// error Connot assign to value:&#x27;c&#x27; is a &#x27;let&#x27; constant</span></span><br></pre></td></tr></table></figure>

<p>其他类型也可以声明为常量。例如，下面的代码将数组声明为一个常量，如果您尝试修改任何元素，那么Swift编译器将报告一个错误：</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> arr2 <span class="operator">=</span> [<span class="number">4</span>, <span class="number">5</span>, <span class="number">6</span>]</span><br><span class="line">arr2[<span class="number">0</span>] <span class="operator">=</span> <span class="number">8</span></span><br><span class="line">print (arr2)    <span class="comment">// [8, 5, 6]</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> arr <span class="operator">=</span> [<span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>]</span><br><span class="line">a[<span class="number">0</span>] <span class="operator">=</span> <span class="number">5</span>    <span class="comment">// error Use of unresolved identifier &#x27;a&#x27;</span></span><br></pre></td></tr></table></figure>



<h4 id="可选-Optionals-类型"><a href="#可选-Optionals-类型" class="headerlink" title="可选(Optionals)类型"></a>可选(Optionals)类型</h4><p>常量声明时需要初始化，变量需要在使用前初始化。 那么objectivec中<code>nil</code>等价在哪呢？ Swift引入了可选值。 可选的值可以有一个值或<code>nil</code>。 如果你看看下面的代码，你会注意到<code>x</code>被指定了一个2014的可选值。这意味着Swift编译器意识到x也可能是<code>nil</code>。</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> s <span class="operator">=</span> <span class="string">&quot;2014&quot;</span></span><br><span class="line"><span class="keyword">var</span> x <span class="operator">=</span> <span class="type">Int</span>(s)</span><br><span class="line"><span class="built_in">print</span>(x)    <span class="comment">// Optional(2014)</span></span><br></pre></td></tr></table></figure>

<p>如果你在这个代码中进行了修改，并且把值<code>“abc”</code>赋值给<code>s</code>，而这个值不能被转换成Integer，你会注意到<code>x</code>现在是<code>nil</code>。</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> s <span class="operator">=</span> <span class="string">&quot;abc&quot;</span></span><br><span class="line"><span class="keyword">var</span> x <span class="operator">=</span> <span class="type">Int</span>(s)</span><br><span class="line"><span class="built_in">print</span>(x)    <span class="comment">// nil</span></span><br></pre></td></tr></table></figure>

<p> <code>Int()</code> 函数的返回类型是<code>Int</code>？，它是一个可选的<code>Int</code>。让我们试着在<code>x</code>上调用一个标准函数：</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> x <span class="operator">=</span> <span class="type">Int</span>(<span class="string">&quot;2014&quot;</span>)</span><br><span class="line"><span class="built_in">print</span>(x.successor()) <span class="comment">// error</span></span><br></pre></td></tr></table></figure>

<p>编译器发出一个错误信号，因为x是可选的，可能是<code>nil</code>。我们必须首先测试<code>x</code>，并确保后继函数在实数上被调用，而不是<code>nil</code>：</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> x <span class="operator">=</span> <span class="type">Int</span>(<span class="string">&quot;2014&quot;</span>)</span><br><span class="line"><span class="keyword">if</span> x <span class="operator">!=</span> <span class="literal">nil</span></span><br><span class="line">&#123;</span><br><span class="line">  <span class="built_in">print</span>(x<span class="operator">!</span>.successor())    <span class="comment">// 2015</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p><strong>请注意，我们必须通过附加感叹号 (!)来解包<code>x</code><strong>。 当我们确定x包含一个值时，我们可以访问它。 否则，我们将得到一个运行时错误。 我们也可对Swift调用进行</strong>可选绑定</strong>，将可选变量转换为非可选变量</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> x <span class="operator">=</span> <span class="string">&quot;123&quot;</span>.toInt()</span><br><span class="line"><span class="keyword">if</span> <span class="keyword">let</span> y <span class="operator">=</span> x</span><br><span class="line">&#123;</span><br><span class="line">  <span class="built_in">print</span>(y)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>if语句中的代码只会在<code>x</code>有值时执行，并将其赋值给<code>y</code>。 请注意，我们不需要展开<code>y</code>，它的类型不是可选的，因为我们知道<code>x</code>不是<code>nil</code>。</p>
<p>苹果的Swift教程，阅读关于可选和新特性等更多细节</p>
<p><a target="_blank" rel="noopener" href="https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/OptionalChaining.html#//apple_ref/doc/uid/TP40014097-CH21-XID_356">Optional Chaining</a></p>
<h4 id="字符串插值（拼接）"><a href="#字符串插值（拼接）" class="headerlink" title="字符串插值（拼接）"></a>字符串插值（拼接）</h4><p>在objectivec中，字符串通常用<code>stringWithFormat：</code>方法完成：</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">NSString</span> <span class="operator">*</span>user <span class="operator">=</span> @<span class="string">&quot;Gabriel&quot;</span>;</span><br><span class="line">int days <span class="operator">=</span> <span class="number">3</span>;</span><br><span class="line"><span class="type">NSString</span> <span class="operator">*</span>s <span class="operator">=</span> [<span class="type">NSString</span> stringWithFormat:@<span class="string">&quot;posted by %@ (%d days ago)&quot;</span>, user, days];</span><br></pre></td></tr></table></figure>

<p>您也可以使用表达式:</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> width <span class="operator">=</span> <span class="number">2</span></span><br><span class="line"><span class="keyword">let</span> height <span class="operator">=</span> <span class="number">3</span></span><br><span class="line"><span class="keyword">let</span> s <span class="operator">=</span> <span class="string">&quot;Area for square with sides <span class="subst">\(width)</span> and <span class="subst">\(height)</span> is <span class="subst">\(width<span class="operator">*</span>height)</span>&quot;</span></span><br></pre></td></tr></table></figure>

<p>了解更多关于swift的字符串插值和其他新功能, <a target="_blank" rel="noopener" href="https://developer.apple.com/library/ios/documentation/swift/conceptual/swift_programming_language/StringsAndCharacters.html#//apple_ref/doc/uid/TP40014097-CH7-XID_418">请点击这里 </a>。</p>
<h4 id="函数"><a href="#函数" class="headerlink" title="函数"></a>函数</h4><p>Swift中的函数定义与C不同。函数定义如下：</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">func</span> <span class="title function_">someFunction</span>(<span class="params">s</span>:<span class="type">String</span>, <span class="params">i</span>: <span class="type">Int</span>) -&gt; <span class="type">Bool</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="operator">...</span>    <span class="comment">// code</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>Swift函数是一流的类型。这意味着您可以将函数分配给变量，将它们作为参数传递给其他函数，或者使它们返回类型：</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">func</span> <span class="title function_">stringLength</span>(<span class="params">s</span>:<span class="type">String</span>) -&gt; <span class="type">Int</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">return</span> countElements(s)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">func</span> <span class="title function_">stringValue</span>(<span class="params">s</span>:<span class="type">String</span>) -&gt; <span class="type">Int</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">if</span> <span class="keyword">let</span> x <span class="operator">=</span> s.toInt()</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">return</span> x</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">return</span> <span class="number">0</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">func</span> <span class="title function_">doSomething</span>(<span class="params">f</span>:<span class="type">String</span> -&gt; <span class="type">Int</span>, <span class="params">s</span>:<span class="type">String</span>) -&gt; <span class="type">Int</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">return</span> f(s).successor()</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> f1 <span class="operator">=</span> stringLength</span><br><span class="line"><span class="keyword">let</span> f2 <span class="operator">=</span> stringValue</span><br><span class="line"></span><br><span class="line">doSomething(f1, <span class="string">&quot;123&quot;</span>)    <span class="comment">// 4</span></span><br><span class="line">doSomething(f2, <span class="string">&quot;123&quot;</span>)    <span class="comment">// 124</span></span><br></pre></td></tr></table></figure>

<p>同样，Swift推断f1和f2（String - &gt; Int）的类型，虽然我们可以明确地定义它们：</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> f1:<span class="type">String</span> -&gt; <span class="type">Int</span> <span class="operator">=</span> stringLength</span><br></pre></td></tr></table></figure>

<p>函数也可以返回其他函数：</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">func</span> <span class="title function_">compareGreaterThan</span>(<span class="params">a</span>: <span class="type">Int</span>, <span class="params">b</span>: <span class="type">Int</span>) -&gt; <span class="type">Bool</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">return</span> a <span class="operator">&gt;</span> b</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">func</span> <span class="title function_">compareLessThan</span>(<span class="params">a</span>: <span class="type">Int</span>, <span class="params">b</span>: <span class="type">Int</span>) -&gt; <span class="type">Bool</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">return</span> a <span class="operator">&lt;</span> b</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">func</span> <span class="title function_">comparator</span>(<span class="params">greaterThan</span>:<span class="type">Bool</span>) -&gt; (<span class="type">Int</span>, <span class="type">Int</span>) -&gt; <span class="type">Bool</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">if</span> greaterThan</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">return</span> compareGreaterThan</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">return</span> compareLessThan</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> f <span class="operator">=</span> comparator(<span class="literal">true</span>)</span><br><span class="line">println(f(<span class="number">5</span>, <span class="number">9</span>))</span><br></pre></td></tr></table></figure>

<p>Swift中的函数指南可以在<a target="_blank" rel="noopener" href="https://developer.apple.com/library/ios/documentation/swift/conceptual/swift_programming_language/Functions.html#//apple_ref/doc/uid/TP40014097-CH10-XID_243">这里</a>找到。</p>
<h4 id="枚举（Enumerations）"><a href="#枚举（Enumerations）" class="headerlink" title="枚举（Enumerations）"></a>枚举（Enumerations）</h4><p>Swift中的枚举比objectivec中的枚举强大得多。 作为Swift的结构体(structs)，他们可以有方法，也可以传值</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">enum</span> <span class="title class_">MobileDevice</span> : <span class="title class_">String</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">case</span> iPhone <span class="operator">=</span> <span class="string">&quot;iPhone&quot;</span>, <span class="type">Android</span> <span class="operator">=</span> <span class="string">&quot;Android&quot;</span>, <span class="type">WP8</span> <span class="operator">=</span> <span class="string">&quot;Windows Phone8&quot;</span>, <span class="type">BB</span> <span class="operator">=</span> <span class="string">&quot;BlackBerry&quot;</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">func</span> <span class="title function_">name</span>() -&gt; <span class="type">String</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">self</span>.toRaw()</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">let</span> m <span class="operator">=</span> <span class="type">MobileDevice</span>.<span class="type">Android</span></span><br><span class="line"><span class="built_in">print</span>(m.name())    <span class="comment">// &quot;Android&quot;</span></span><br></pre></td></tr></table></figure>

<p>与objectivec不同，swift枚举可以为每个成员赋值字符串(Strings)，字符(characters)或浮点数(floats)，除了整数(integers)。<code>toraw()</code>方法很方便的返回分配给每个成员的值。</p>
<p>枚举也可以参数化:</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">enum</span> <span class="title class_">Location</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">case</span> <span class="type">Address</span>(street:<span class="type">String</span>, city:<span class="type">String</span>)</span><br><span class="line">    <span class="keyword">case</span> <span class="type">LatLon</span>(lat:<span class="type">Float</span>, lon:<span class="type">Float</span>)</span><br><span class="line"></span><br><span class="line">    <span class="keyword">func</span> <span class="title function_">description</span>() -&gt; <span class="type">String</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">switch</span> <span class="keyword">self</span></span><br><span class="line">        &#123;</span><br><span class="line">        <span class="keyword">case</span> <span class="keyword">let</span> .<span class="type">Address</span>(street, city):</span><br><span class="line">            <span class="keyword">return</span> street <span class="operator">+</span> <span class="string">&quot;, &quot;</span> <span class="operator">+</span> city</span><br><span class="line">        <span class="keyword">case</span> <span class="keyword">let</span> .<span class="type">LatLon</span>(lat, lon):</span><br><span class="line">            <span class="keyword">return</span> <span class="string">&quot;(<span class="subst">\(lat)</span>, <span class="subst">\(lon)</span>)&quot;</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">let</span> loc1 <span class="operator">=</span> <span class="type">Location</span>.<span class="type">Address</span>(street: <span class="string">&quot;2070 Fell St&quot;</span>, city: <span class="string">&quot;San Francisco&quot;</span>)</span><br><span class="line"><span class="keyword">let</span> loc2 <span class="operator">=</span> <span class="type">Location</span>.<span class="type">LatLon</span>(lat: <span class="number">23.117</span>, lon: <span class="number">45.899</span>)</span><br><span class="line"><span class="built_in">print</span>(loc1.description())        <span class="comment">// &quot;2070 Fell St, San Francisco&quot;</span></span><br><span class="line"><span class="built_in">print</span>(loc2.description())        <span class="comment">// &quot;(23.117, 45.988)&quot;</span></span><br></pre></td></tr></table></figure>

<p>更多关于枚举可用的信息 <a target="_blank" rel="noopener" href="https://developer.apple.com/library/ios/documentation/swift/conceptual/swift_programming_language/Enumerations.html#//apple_ref/doc/uid/TP40014097-CH12-XID_223">在这里 </a>。</p>
<h4 id="元组（Tuples）"><a href="#元组（Tuples）" class="headerlink" title="元组（Tuples）"></a>元组（Tuples）</h4><p>元组将多个值组合为一个复合值。元组中的值可以是任何类型，不必是彼此相同的类型。</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> person <span class="operator">=</span> (<span class="string">&quot;Gabriel&quot;</span>, <span class="string">&quot;Kirkpatrick&quot;</span>)</span><br><span class="line"><span class="built_in">print</span>(person.<span class="number">0</span>) <span class="comment">// Gabriel</span></span><br></pre></td></tr></table></figure>

<p>你也可以命名单个的元组元素：</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> person <span class="operator">=</span> (first: <span class="string">&quot;Gabriel&quot;</span>, last: <span class="string">&quot;Kirkpatrick&quot;</span>)</span><br><span class="line"><span class="built_in">print</span>(person.first)</span><br></pre></td></tr></table></figure>

<p>元组对于需要返回多个值的函数返回类型非常方便：</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">func</span> <span class="title function_">intDivision</span>(<span class="params">a</span>: <span class="type">Int</span>, <span class="params">b</span>: <span class="type">Int</span>) -&gt; (quotient: <span class="type">Int</span>, remainder: <span class="type">Int</span>)</span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">return</span> (a<span class="operator">/</span>b, a<span class="operator">%</span>b)</span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">print</span>(intDivision(<span class="number">11</span>, <span class="number">3</span>))    <span class="comment">// (3, 2)</span></span><br><span class="line"><span class="keyword">let</span> result <span class="operator">=</span> intDivision(<span class="number">15</span>, <span class="number">4</span>)</span><br><span class="line"><span class="built_in">print</span>(result.remainder)    <span class="comment">// 3</span></span><br></pre></td></tr></table></figure>

<p>不像objectivec，swift支持switch语句中的模式(pattern)匹配：</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> complex <span class="operator">=</span> (<span class="number">2.0</span>, <span class="number">1.1</span>)    <span class="comment">// real and imaginary parts</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">switch</span> complex</span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">case</span> (<span class="number">0</span>, <span class="number">0</span>):</span><br><span class="line">        println(<span class="string">&quot;Number is zero&quot;</span>)</span><br><span class="line">    <span class="keyword">case</span> (<span class="keyword">_</span>, <span class="number">0</span>):</span><br><span class="line">        println(<span class="string">&quot;Number is real&quot;</span>)</span><br><span class="line">    <span class="keyword">default</span>:</span><br><span class="line">        println(<span class="string">&quot;Number is imaginary&quot;</span>)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>在第二种情况下，我们不关心数字的实际部分，所以我们使用<code>_</code>来匹配任何东西。您还可以检查每种情况下的附加条件。为此，我们需要将模式值绑定到常量：</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> complex <span class="operator">=</span> (<span class="number">2.0</span>, <span class="number">1.1</span>)</span><br><span class="line"></span><br><span class="line"><span class="keyword">switch</span> complex</span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">case</span> (<span class="number">0</span>, <span class="number">0</span>):</span><br><span class="line">        println(<span class="string">&quot;Number is zero&quot;</span>)</span><br><span class="line">    <span class="keyword">case</span> (<span class="keyword">let</span> a, <span class="number">0</span>) <span class="keyword">where</span> a <span class="operator">&gt;</span> <span class="number">0</span>:</span><br><span class="line">        println(<span class="string">&quot;Number is real and positive&quot;</span>)</span><br><span class="line">    <span class="keyword">case</span> (<span class="keyword">let</span> a, <span class="number">0</span>) <span class="keyword">where</span> a <span class="operator">&lt;</span> <span class="number">0</span>:</span><br><span class="line">        println(<span class="string">&quot;Number is real and negative&quot;</span>)</span><br><span class="line">    <span class="keyword">case</span> (<span class="number">0</span>, <span class="keyword">let</span> b) <span class="keyword">where</span> b <span class="operator">!=</span> <span class="number">0</span>:</span><br><span class="line">        println(<span class="string">&quot;Number has only imaginary part&quot;</span>)</span><br><span class="line">    <span class="keyword">case</span> <span class="keyword">let</span> (a, b):</span><br><span class="line">        println(<span class="string">&quot;Number is imaginary with distance <span class="subst">\(a<span class="operator">*</span>a <span class="operator">+</span> b<span class="operator">*</span>b)</span>&quot;</span>)</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>注意我们只需要绑定我们要在比较或case语句中使用的值。阅读更多关于元组，<a target="_blank" rel="noopener" href="https://developer.apple.com/library/prerelease/mac/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html#//apple_ref/doc/uid/TP40014097-CH5-XID_483">点击这里</a>。</p>
<h4 id="类-Classes-和结构-Structures"><a href="#类-Classes-和结构-Structures" class="headerlink" title="类(Classes)和结构(Structures)"></a>类(Classes)和结构(Structures)</h4><p>与objectivec不同，swift不需要为自定义的类和结构创建单独的接口和实现文件。当你学习Swift，你将学会在一个单独的文件中定义一个类或者一个结构体，并且这个类或者结构体的外部接口被自动地提供给其他代码使用。</p>
<h3 id="定义类（Classes）"><a href="#定义类（Classes）" class="headerlink" title="定义类（Classes）"></a>定义类（Classes）</h3><p>类定义很简单:</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Bottle</span></span><br><span class="line">&#123;</span><br><span class="line">   <span class="keyword">var</span> volume: <span class="type">Int</span> <span class="operator">=</span> <span class="number">1000</span></span><br><span class="line"></span><br><span class="line">   <span class="keyword">func</span> <span class="title function_">description</span>() -&gt; <span class="type">String</span></span><br><span class="line">   &#123;</span><br><span class="line">       <span class="keyword">return</span> <span class="string">&quot;This bottle has <span class="subst">\(volume)</span> ml&quot;</span></span><br><span class="line">   &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">let</span> b <span class="operator">=</span> <span class="type">Bottle</span>()</span><br><span class="line"><span class="built_in">print</span>(b.description())</span><br></pre></td></tr></table></figure>

<p>正如你所看到的，声明(header)和实现(implementation)在同一个文件中。swift不再使用头文件和实现文件。让我们给我们的例子添加一个标签：</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Bottle</span></span><br><span class="line">&#123;</span><br><span class="line">   <span class="keyword">var</span> volume: <span class="type">Int</span> <span class="operator">=</span> <span class="number">1000</span></span><br><span class="line">   <span class="keyword">var</span> label:<span class="type">String</span></span><br><span class="line"></span><br><span class="line">   <span class="keyword">func</span> <span class="title function_">description</span>() -&gt; <span class="type">String</span></span><br><span class="line">   &#123;</span><br><span class="line">       <span class="keyword">return</span> <span class="string">&quot;This bottle of <span class="subst">\(label)</span> has <span class="subst">\(volume)</span> ml&quot;</span></span><br><span class="line">   &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>编译器会抱怨,因为是一个可选的变量标签和瓶时不会持有一个值实例化。 我们需要添加一个初始化程序:</p>
<p>编译器会抱怨，因为标签是一个非可选的变量，并且当一个Bottle被实例化时不会保存一个值。我们需要添加一个初始化程序(initializer)：</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Bottle</span></span><br><span class="line">&#123;</span><br><span class="line">   <span class="keyword">var</span> volume: <span class="type">Int</span> <span class="operator">=</span> <span class="number">1000</span></span><br><span class="line">   <span class="keyword">var</span> label:<span class="type">String</span></span><br><span class="line"></span><br><span class="line">   <span class="keyword">init</span>(<span class="params">label</span>:<span class="type">String</span>)</span><br><span class="line">   &#123;</span><br><span class="line">       <span class="keyword">self</span>.label <span class="operator">=</span> label</span><br><span class="line">   &#125;</span><br><span class="line"></span><br><span class="line">   <span class="keyword">func</span> <span class="title function_">description</span>() -&gt; <span class="type">String</span></span><br><span class="line">   &#123;</span><br><span class="line">       <span class="keyword">return</span> <span class="string">&quot;This bottle of <span class="subst">\(label)</span> has <span class="subst">\(volume)</span> ml&quot;</span></span><br><span class="line">   &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>或者，我们可以使用可选类型的属性，它不会被初始化。在下面的例子中，我们将卷设为一个可选的整数：</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Bottle</span></span><br><span class="line">&#123;</span><br><span class="line">   <span class="keyword">var</span> volume: <span class="type">Int</span>?</span><br><span class="line">   <span class="keyword">var</span> label:<span class="type">String</span></span><br><span class="line"></span><br><span class="line">   <span class="keyword">init</span>(<span class="params">label</span>:<span class="type">String</span>)</span><br><span class="line">   &#123;</span><br><span class="line">       <span class="keyword">self</span>.label <span class="operator">=</span> label</span><br><span class="line">   &#125;</span><br><span class="line"></span><br><span class="line">   <span class="keyword">func</span> <span class="title function_">description</span>() -&gt; <span class="type">String</span></span><br><span class="line">   &#123;</span><br><span class="line">        <span class="keyword">if</span> <span class="keyword">self</span>.volume <span class="operator">!=</span> <span class="literal">nil</span></span><br><span class="line">        &#123;</span><br><span class="line">               <span class="keyword">return</span> <span class="string">&quot;This bottle of <span class="subst">\(label)</span> has <span class="subst">\(volume<span class="operator">!</span>)</span> ml&quot;</span></span><br><span class="line">           &#125;</span><br><span class="line">           <span class="keyword">else</span></span><br><span class="line">           &#123;</span><br><span class="line">               <span class="keyword">return</span> <span class="string">&quot;A bootle of <span class="subst">\(label)</span>&quot;</span></span><br><span class="line">           &#125;</span><br><span class="line">   &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<h3 id="结构-Structures"><a href="#结构-Structures" class="headerlink" title="结构(Structures)"></a>结构(Structures)</h3><p>Swift语言也有 <code>结构体</code>,但是比objective - c更加灵活。 下面的代码教程定义了一个结构体：</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">struct</span> <span class="title class_">Seat</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">var</span> row: <span class="type">Int</span></span><br><span class="line">    <span class="keyword">var</span> letter:<span class="type">String</span></span><br><span class="line"></span><br><span class="line">    <span class="keyword">init</span> (<span class="params">row</span>: <span class="type">Int</span>, <span class="params">letter</span>:<span class="type">String</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">self</span>.row <span class="operator">=</span> row</span><br><span class="line">        <span class="keyword">self</span>.letter <span class="operator">=</span> letter</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">func</span> <span class="title function_">description</span>() -&gt; <span class="type">String</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="string">&quot;<span class="subst">\(row)</span>-<span class="subst">\(letter)</span>&quot;</span></span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>像swift中的类，结构可以有方法，属性，初始值设定项，并符合协议。类和结构之间的主要区别是类是通过引用传递的，而结构则是通过值传递的。</p>
<p>这个例子演示了通过引用传递类：</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">let</span> b <span class="operator">=</span> <span class="type">Bottle</span>()</span><br><span class="line"><span class="built_in">print</span>(b.description())    <span class="comment">// &quot;b&quot; bottle has 1000 ml</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> b2 <span class="operator">=</span> b</span><br><span class="line">b.volume <span class="operator">=</span> <span class="number">750</span></span><br><span class="line"><span class="built_in">print</span>(b2.description())    <span class="comment">// &quot;b&quot; and &quot;b2&quot; bottles have 750 ml</span></span><br></pre></td></tr></table></figure>

<p>如果我们用struct来尝试类似的情况，你会注意到变量是按值传递的：</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> s1 <span class="operator">=</span> <span class="type">Seat</span>(row: <span class="number">14</span>, letter:<span class="string">&quot;A&quot;</span>)</span><br><span class="line"><span class="keyword">var</span> s2 <span class="operator">=</span> s1</span><br><span class="line">s1.letter <span class="operator">=</span> <span class="string">&quot;B&quot;</span></span><br><span class="line"><span class="built_in">print</span>(s1.description())    <span class="comment">// 14-B</span></span><br><span class="line"><span class="built_in">print</span>(s2.description())    <span class="comment">// 14-A</span></span><br></pre></td></tr></table></figure>

<p> 什么时候应该使用struct，什么时候应该使用class？</p>
<p>​       就像在objectivec和c中一样，当你需要对几个值进行分组时，使用结构体，并期望它们被复制而不是被引用。 例如，复数，，2d或3d点或RGB颜色。</p>
<p>​       一个类的实例传统上被称为对象。 然而，Swift类和结构在功能上比其他语言更接近，而且许多功能可以应用于类或结构类型的实例。 正因为如此，在Swift引用中使用的更一般的术语是实例(instance)，它适用于这两者中的任何一个。</p>
<h3 id="属性-Properties"><a href="#属性-Properties" class="headerlink" title="属性(Properties)"></a>属性(Properties)</h3><p>正如我们前面看到的，Swift中的属性在类或结构定义中用<code>var</code>关键字声明。 我们也可以用<code>let</code>语句声明常量。</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">struct</span> <span class="title class_">FixedPointNumber</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">var</span> digits: <span class="type">Int</span></span><br><span class="line">    <span class="keyword">let</span> decimals: <span class="type">Int</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> n <span class="operator">=</span> <span class="type">FixedPointNumber</span>(digits: <span class="number">12345</span>, decimals: <span class="number">2</span>)</span><br><span class="line">n.digits <span class="operator">=</span> <span class="number">4567</span>    <span class="comment">// ok</span></span><br><span class="line">n.decimals <span class="operator">=</span> <span class="number">3</span>     <span class="comment">// error, decimals is a constant</span></span><br></pre></td></tr></table></figure>

<p>另外请记住，强类型属性是强引用的，除非用weak关键字作为前缀。 但是，有一些weak的非可选属性，所以请阅读苹果Swift指南中的<a target="_blank" rel="noopener" href="https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html#//apple_ref/doc/uid/TP40014097-CH20-XID_88">自动引用计数章节</a>。</p>
<h3 id="计算属性-Computed-Properties"><a href="#计算属性-Computed-Properties" class="headerlink" title="计算属性(Computed Properties)"></a>计算属性(Computed Properties)</h3><p>计算属性实际上并不存储一个值。 相反，它们提供了一个getter和一个可选的setter来间接检索和设置其他属性和值。</p>
<p>以下代码提供了一个计算<code>sign</code>值的示例：</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">enum</span> <span class="title class_">Sign</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">case</span> <span class="type">Positive</span></span><br><span class="line">    <span class="keyword">case</span> <span class="type">Negative</span></span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">struct</span> <span class="title class_">SomeNumber</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">var</span> number:<span class="type">Int</span></span><br><span class="line">    <span class="keyword">var</span> sign:<span class="type">Sign</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">get</span></span><br><span class="line">        &#123;</span><br><span class="line">            <span class="keyword">if</span> number <span class="operator">&lt;</span> <span class="number">0</span></span><br><span class="line">            &#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="type">Sign</span>.<span class="type">Negative</span></span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span></span><br><span class="line">            &#123;</span><br><span class="line">                <span class="keyword">return</span> <span class="type">Sign</span>.<span class="type">Positive</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">set</span> (newSign)</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="keyword">if</span> (newSign <span class="operator">==</span> <span class="type">Sign</span>.<span class="type">Negative</span>)</span><br><span class="line">            &#123;</span><br><span class="line">                <span class="keyword">self</span>.number <span class="operator">=</span> <span class="operator">-</span><span class="built_in">abs</span>(<span class="keyword">self</span>.number)</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span></span><br><span class="line">            &#123;</span><br><span class="line">                <span class="keyword">self</span>.number <span class="operator">=</span> <span class="built_in">abs</span>(<span class="keyword">self</span>.number)</span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>我们也可以通过执行一个getter来定义只读属性：</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">struct</span> <span class="title class_">SomeNumber</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">var</span> number:<span class="type">Int</span></span><br><span class="line">    <span class="keyword">var</span> isEven:<span class="type">Bool</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">get</span></span><br><span class="line">        &#123;</span><br><span class="line">            <span class="keyword">return</span> number <span class="operator">%</span> <span class="number">2</span> <span class="operator">==</span> <span class="number">0</span></span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>在objectivec中，属性通常由一个实例变量持有，由编译器明确地声明或自动创建。 在Swift中，另一方面，一个属性没有相应的实例变量。 也就是说，属性的后备存储不能直接访问。 假设我们在objectivec中有这个</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// .h</span></span><br><span class="line"><span class="meta">@interface</span> <span class="type">OnlyInitialString</span> : <span class="type">NSObject</span></span><br><span class="line"></span><br><span class="line"><span class="meta">@property</span>(strong) <span class="type">NSString</span> <span class="operator">*</span>string;</span><br><span class="line"></span><br><span class="line"><span class="meta">@end</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// .m</span></span><br><span class="line"></span><br><span class="line"><span class="meta">@implementation</span> <span class="type">OnlyInitialString</span></span><br><span class="line"></span><br><span class="line"><span class="operator">-</span> (void)setString:(<span class="type">NSString</span> <span class="operator">*</span>newString)</span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">if</span> (newString.length <span class="operator">&gt;</span> <span class="number">0</span>)</span><br><span class="line">    &#123;</span><br><span class="line">        _string <span class="operator">=</span> [newString substringToIndex:<span class="number">1</span>];</span><br><span class="line">    &#125;</span><br><span class="line">    <span class="keyword">else</span></span><br><span class="line">    &#123;</span><br><span class="line">        _string <span class="operator">=</span> @<span class="string">&quot;&quot;</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="meta">@end</span></span><br></pre></td></tr></table></figure>

<p>因为在Swift中，计算属性没有后备存储，所以我们需要这样做：</p>
<figure class="highlight swift"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">OnlyInitialString</span></span><br><span class="line">&#123;</span><br><span class="line">    <span class="keyword">var</span> initial:<span class="type">String</span> <span class="operator">=</span> <span class="string">&quot;&quot;</span></span><br><span class="line">    <span class="keyword">var</span> string:<span class="type">String</span></span><br><span class="line">    &#123;</span><br><span class="line">        <span class="keyword">set</span> (newString)</span><br><span class="line">        &#123;</span><br><span class="line">            <span class="keyword">if</span> countElements(newString) <span class="operator">&gt;</span> <span class="number">0</span></span><br><span class="line">            &#123;</span><br><span class="line">                <span class="keyword">self</span>.initial <span class="operator">=</span> newString.substringToIndex(advance(newString.startIndex, <span class="number">1</span>))</span><br><span class="line">            &#125;</span><br><span class="line">            <span class="keyword">else</span></span><br><span class="line">            &#123;</span><br><span class="line">                <span class="keyword">self</span>.initial <span class="operator">=</span> <span class="string">&quot;&quot;</span></span><br><span class="line">            &#125;</span><br><span class="line">        &#125;</span><br><span class="line">        <span class="keyword">get</span></span><br><span class="line">        &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">self</span>.initial</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<p>关于属性更详细地解释 <a target="_blank" rel="noopener" href="https://developer.apple.com/library/ios/documentation/swift/conceptual/swift_programming_language/Properties.html#//apple_ref/doc/uid/TP40014097-CH14-XID_368">在这里</a></p>
</div></article><div class="post-copyright"><div class="post-copyright__author"><span class="post-copyright-meta">文章作者: </span><span class="post-copyright-info"><a href="mailto:undefined">kyren</a></span></div><div class="post-copyright__type"><span class="post-copyright-meta">文章链接: </span><span class="post-copyright-info"><a href="http://huluo666.gitee.io/2017/01/28/iOS开发者指南：从Objective-C到Swift的学习/">http://huluo666.gitee.io/2017/01/28/iOS开发者指南：从Objective-C到Swift的学习/</a></span></div><div class="post-copyright__notice"><span class="post-copyright-meta">版权声明: </span><span class="post-copyright-info">本博客所有文章除特别声明外，均采用 <a target="_blank" rel="noopener" href="https://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY-NC-SA 4.0</a> 许可协议。转载请注明来自 <a href="http://huluo666.gitee.io">Kyren's Blog</a>！</span></div></div><div class="post-meta__tag-list"><a class="post-meta__tags" href="/tags/Swift/">Swift</a></div><nav id="pagination"><div class="prev-post pull-left"><a href="/2017/02/03/Mac%20Nginx%E6%9C%8D%E5%8A%A1%E5%99%A8%E6%90%AD%E5%BB%BA/"><i class="fa fa-chevron-left">  </i><span>Mac Nginx服务器搭建</span></a></div><div class="next-post pull-right"><a href="/2016/12/28/Mac%E5%9B%BE%E7%89%87%E5%8E%8B%E7%BC%A9_shell/"><span>图片无损压缩工具</span><i class="fa fa-chevron-right"></i></a></div></nav></div></div><footer><div class="layout" id="footer"><div class="copyright">&copy;2022 By kyren</div><div class="framework-info"><span>驱动 - </span><a target="_blank" rel="noopener" href="http://hexo.io"><span>Hexo</span></a><span class="footer-separator">|</span><span>主题 - </span><a target="_blank" rel="noopener" href="https://github.com/Molunerfinn/hexo-theme-melody"><span>Melody</span></a></div><div class="footer_custom_text">hitokoto</div><div class="busuanzi"><script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script><span id="busuanzi_container_page_pv"><i class="fa fa-file"></i><span id="busuanzi_value_page_pv"></span><span></span></span></div></div></footer><i class="fa fa-arrow-up" id="go-up" aria-hidden="true"></i><script src="https://cdn.jsdelivr.net/npm/animejs@latest/lib/anime.min.js"></script><script src="https://cdn.jsdelivr.net/npm/jquery@latest/dist/jquery.min.js"></script><script src="https://cdn.jsdelivr.net/npm/@fancyapps/fancybox@latest/dist/jquery.fancybox.min.js"></script><script src="https://cdn.jsdelivr.net/npm/velocity-animate@latest/velocity.min.js"></script><script src="https://cdn.jsdelivr.net/npm/velocity-ui-pack@latest/velocity.ui.min.js"></script><script src="/js/utils.js?version=1.9.0"></script><script src="/js/fancybox.js?version=1.9.0"></script><script src="/js/sidebar.js?version=1.9.0"></script><script src="/js/copy.js?version=1.9.0"></script><script src="/js/fireworks.js?version=1.9.0"></script><script src="/js/transition.js?version=1.9.0"></script><script src="/js/scroll.js?version=1.9.0"></script><script src="/js/head.js?version=1.9.0"></script><script src="/js/search/local-search.js"></script><script>if(/Android|webOS|iPhone|iPod|iPad|BlackBerry/i.test(navigator.userAgent)) {
  $('#nav').addClass('is-mobile')
  $('footer').addClass('is-mobile')
  $('#top-container').addClass('is-mobile')
}</script><div class="search-dialog" id="local-search"><div class="search-dialog__title" id="local-search-title">本地搜索</div><div id="local-input-panel"><div id="local-search-input"><div class="local-search-box"><input class="local-search-box--input" placeholder="搜索文章"></div></div></div><hr><div id="local-search-results"><div id="local-hits"></div><div id="local-stats"><div class="local-search-stats__hr" id="hr"><span>由</span> <a target="_blank" rel="noopener" href="https://github.com/wzpan/hexo-generator-search" style="color:#49B1F5;">hexo-generator-search</a>
 <span>提供支持</span></div></div></div><span class="search-close-button"><i class="fa fa-times"></i></span></div><div class="search-mask"></div></body></html>